/**
 * @file    common_msg_queue.c
 * @author  yhy
 * @brief   消息队列
 * @version 1.00
 * @date    2025-07-09
 *
 * @copyright Copyright (c) 2025
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-07-02     yhy          the first version V1.00
 *
 */
#include "common_msg_queue.h"

#define _DI() /* __disable_irq() */
#define _EI() /* __enable_irq() */

/**
 * @brief 初始化消息队列
 *
 * @param queue              消息队列
 * @param msg_frame_buf      消息帧缓冲区
 * @param depth              队列深度
 */
void common_queue_init(msg_queue_t *queue, msg_frame_t *msg_frame_buf, uint32_t depth)
{
    queue->front         = 0;
    queue->rear          = 0;
    queue->count         = 0;
    queue->msg_frame_buf = msg_frame_buf;
    queue->depth         = depth;
}

/**
 * @brief 判断队列是否为空
 *
 * @param queue          消息队列
 * @return true          队列为空
 * @return false         队列不为空
 */
bool common_queue_is_empty(msg_queue_t *queue)
{
    _DI();
    bool ret_val = false;
    if (queue->count == 0U) {
        ret_val = true;
    }
    else {}
    _EI();
    return ret_val;
}

/**
 * @brief 判断队列是否满
 *
 * @param queue          消息队列
 * @return true          队列满
 * @return false         队列未满
 */
bool common_queue_is_full(msg_queue_t *queue)
{
    bool ret_val = false;
    _DI();
    if (queue->count >= queue->depth) {
        ret_val = true;
    }
    else {}
    _EI();
    return ret_val;
}

/**
 * @brief 消息帧入队
 *
 * @param queue          消息队列
 * @param can_frame      消息帧
 * @return true          入队成功
 * @return false         入队失败, 队列满时失败
 */
bool common_queue_push(msg_queue_t *queue, msg_frame_t can_frame)
{
    bool ret_val = true;
    _DI();
    /* Queue is full */
    if (queue->count >= queue->depth) {
        ret_val = false;
    }
    else {
        queue->msg_frame_buf[queue->rear] = can_frame;
        queue->rear                       = (queue->rear + 1) % queue->depth;
        queue->count++;
    }
    _EI();
    return ret_val;
}

/**
 * @brief 消息帧出队
 *
 * @param queue          消息队列
 * @param can_frame      消息帧
 * @return true          出队成功
 * @return false         出队失败
 */
bool common_queue_pop(msg_queue_t *queue, msg_frame_t *can_frame)
{
    bool ret_val = true;
    _DI();
    /* Queue is empty */
    if (queue->count == 0) {
        ret_val = false;
    }
    else {
        *can_frame   = queue->msg_frame_buf[queue->front];
        queue->front = (queue->front + 1) % queue->depth;
        queue->count--;
    }
    _EI();
    return ret_val;
}

/**
 * @brief 获取队列剩余深度
 *
 * @param queue          消息队列
 * @return uint16_t      剩余深度
 */
uint16_t common_queue_get_free_depth(msg_queue_t *queue) { return (queue->depth - queue->count); }
